#include "DopplerSpectrumDis.h"
#include <QGridLayout>
#include <QLabel>
#include <QMetaType>
#include "UDPdriver.h"


//初始化固定字符串
const QString  qstr_result_narrow[3] = {"直升机", "螺旋桨飞机", "喷气式飞机"};
const QString  qstr_result_broad[3] = {"Tu16", "B52", "B1B"};

DopplerSpectrumDis::DopplerSpectrumDis(QWidget *parent)
    : QWidget(parent)
{
    qRegisterMetaType<uint32_t>("uint32_t");
    this->setWindowTitle("DopplerDisplay");
//    this->setStyleSheet("background-color:black;");
    //主界面布局
    m_main_layout = new QVBoxLayout();
    m_main_layout->setContentsMargins(0,0,0,0);
    //创建绘图界面groupBox
    m_groupBox_plot = new QGroupBox(tr("Plot-Display"));
    m_groupBox_plot->setStyleSheet("background-color:white");    //设置背景
    //创建属性界面groupBox
    m_groupBox_attribute = new QGroupBox(tr("Attribut-Display"));
    m_groupBox_attribute->setStyleSheet("background-color:white");
    //创建RadioButton
    m_radioButton_broad = new QRadioButton(tr("宽带识别"));
    m_radioButton_broad->setChecked(true);
    m_radioButton_broad_flag = 'B';
    m_radioButton_narrow = new QRadioButton(tr("窄带分类"));
    //创建结果显示标签
    m_label_result = new QLabel(m_groupBox_attribute);

    //groupBox布局设定
    m_layout_vbox = new QVBoxLayout();
    m_layout_hbox = new QHBoxLayout();
    //绘制图形界面实例化
    m_customPlot = new QCustomPlot();
    //配置绘图界面属性
    this->configplot(m_customPlot);

    //groupBox必须设置Box布局
    m_groupBox_plot->setLayout(m_layout_vbox);
    m_groupBox_attribute->setLayout(m_layout_hbox);
    m_groupBox_attribute->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);//设置垂直拉伸不变 水平保证最小

    //布局内添加内容
    m_layout_hbox->addWidget(m_radioButton_broad);
    m_layout_hbox->addWidget(m_radioButton_narrow);
    m_layout_hbox->addWidget(m_label_result);
    m_layout_vbox->addWidget(m_customPlot);

    //主页面布局添加
    m_main_layout->addWidget(m_groupBox_attribute,0);
    m_main_layout->addWidget(m_groupBox_plot,0);
    setLayout(m_main_layout);

    //线程启动
    m_red_thread = new RecDataThread();
    m_red_thread->start();

    this->resize(800,500);

    connect(m_red_thread,SIGNAL(rec_data(uint8_t*,uint, char)),this,SLOT(rec_data_plot(uint8_t*,uint,char)));//接受绘制数据
    connect(this->m_radioButton_broad,SIGNAL(clicked(bool)),this,SLOT(set_broad_status()));//更改数据类型标志位（char）
    connect(this->m_radioButton_narrow,SIGNAL(clicked(bool)),this,SLOT(set_narrow_status()));
    connect(m_red_thread,SIGNAL(rec_result(uint32_t,char)),this,SLOT(set_result_status(uint32_t , char)));//更新数据结果

}

DopplerSpectrumDis::~DopplerSpectrumDis()
{

}

/** 配置曲线图界面参数
 *@author Yguohang
 */
void DopplerSpectrumDis::configplot(QCustomPlot * customPlot)
{

//    customPlot->resize(800,500);
    customPlot->addGraph(0);  //添加数据曲线
    customPlot->graph(0)->setPen(QPen(Qt::blue));  //设置画笔 蓝线
    customPlot->graph(0)->setBrush(QBrush(QColor(0,0,255,60)));
//    customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);   //线型设置
//    customPlot->axisRect()->setupFullAxesBox(false);    //上边沿于下边沿不显示

//    QSizePolicy spRight(QSizePolicy::Preferred, QSizePolicy::Preferred);  //缺省大小为最佳效果 部件允许放大和缩小
//    spRight.setHorizontalStretch(1); //设置水平缩放比例因子
//    spRight.setVerticalStretch(1); //设置垂直缩放比例因子
//    customPlot->setSizePolicy(spRight);
    //自动设置显示界面的范围
    customPlot->graph(0)->rescaleAxes();
    //设置绘制输出图像界面缩放
    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    //设置绘图x轴范围 先固定大小 可设置解析长度
//    customPlot->xAxis->setRange(0, 300);
    //设置绘图y轴范围 y轴范围可不用解析
//    customPlot->yAxis->setRange(0, 255);

    //x轴参数配置
    customPlot->xAxis->setBasePen(QPen(Qt::black));  //基础线
    customPlot->xAxis->setTickPen(QPen(Qt::black));  //刻度
    customPlot->xAxis->grid()->setVisible(true);  //网格线可见
    customPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); //网格线颜色及线样式
    customPlot->xAxis->setTickLabelColor(Qt::black);    //x轴刻度线文字颜色
    customPlot->xAxis->setLabelColor(Qt::black);    //x轴标签颜色
    customPlot->xAxis->setLabel("距离门");    //x轴标签值

    //y轴参数配置
    customPlot->yAxis->setBasePen(QPen(Qt::black));
    customPlot->yAxis->setTickPen(QPen(Qt::black));
    customPlot->yAxis->grid()->setVisible(true);
    customPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine));
    customPlot->yAxis->setTickLabelColor(Qt::black);
    customPlot->yAxis->setLabelColor(Qt::black);
    customPlot->yAxis->setLabel("信号幅值");
}


/**
 * @brief 数据绘图槽函数
 */
void DopplerSpectrumDis::rec_data_plot(uint8_t *data, uint data_size, char type)
{
    QVector<double> Data(data_size);
    QVector<double> Data_size(data_size);
    for(uint32_t i = 0; i<data_size ;i++)
    {
        Data_size[i] = i ;
        Data[i] = *data;
        data++;
    }
    if((type == 'N') && (m_radioButton_narrow_flag =='N'))
    {
        this->m_customPlot->graph(0)->setData(Data_size,Data);
        this->m_customPlot->rescaleAxes(true);
        this->m_customPlot->replot();
    }
    else if((type == 'B') && (m_radioButton_broad_flag == 'B'))
    {
        this->m_customPlot->graph(0)->setData(Data_size,Data);
        this->m_customPlot->rescaleAxes(true);
        this->m_customPlot->replot();
    }
    //清屏
    else
    {
        this->m_customPlot->graph(0)->data().data()->clear();
        this->m_customPlot->replot();
    }

}


void DopplerSpectrumDis::test_data_plot()
{
    QVector<QCPGraphData> timeData(250);
     for (int i=0; i<250; ++i)
     {
       timeData[i].key =i;
       timeData[i].value = i * i;

     }
     m_customPlot->graph()->data()->set(timeData);
}


/**
 * @brief 响应按钮事件 设标志位
 */
void DopplerSpectrumDis::set_narrow_status()
{
    m_radioButton_narrow_flag ='N';
    m_radioButton_broad_flag = '\0';
}

void DopplerSpectrumDis::set_broad_status()
{
    m_radioButton_narrow_flag = '\0';
    m_radioButton_broad_flag = 'B';
}


void DopplerSpectrumDis::set_result_status(uint32_t result, char type)
{
    if((type == 'N') && (m_radioButton_narrow_flag =='N'))
    {
        this->m_label_result->setText("窄带分类结果： " +  qstr_result_narrow[result]);
    }
    else if((type == 'B') && (m_radioButton_broad_flag == 'B'))
    {
        this->m_label_result->setText("宽带识别结果： "+  qstr_result_broad[result]);
    }
    else
    {
        this->m_label_result->setText(tr("无结果"));
    }
}

/****************************************************线程-解析数据**************************************/
#define DEBUG_TEST_VERSION  0


//udp发包数据长度大小
#define FRAME_LENGTH 1280
//字节数据长度大小
#define BYTE_LENGTH 256
//西电固定帧头长度大小
#define XD_FRANME_HEAD_LENGTH 20
//结果8位偏移
#define XD_RESULT_OFFSET 8




/**
 * @brief 数据帧头格式及变量定义
 * @author ygh
 */
//4B:0-3 西电固定帧头
const uint8_t xd_frame_head_high = 0x58;
const uint8_t xd_frame_head_low = 0x44;
//2B:4-5 窄带分类标志位
const uint8_t xd_narrow_high = 0x01;
const uint8_t xd_narrow_low = 0x01;
//2B:4-5 宽带识别标志位
const uint8_t xd_broad_high = 0x01;
const uint8_t xd_broad_low = 0x02;
//2B:6-7 数据长度 32bit数据单位
uint32_t xd_data_length = 0;
//2B:8-9 帧编号
uint8_t xd_frame_number = 0;
//2B:10-11 包编号
uint8_t xd_packet_number = 0;
//2B:12 帧头长度 20B 32bit数据单位
uint32_t xd_frame_length = 0x05;
//2B:13-14 有效数据长度 32bit数据单位
uint32_t xd_valid_data_length = 0;
//8B:20-23 窄带分类结果          //8B:20-23 宽带识别结果
uint32_t xd_sort_result = 0;   uint32_t xd_recognize_result = 0;

uint8_t buffer[FRAME_LENGTH];

RecDataThread::RecDataThread()
{

}

/**
 * @brief 解析数据线程
 */

void RecDataThread::run()
{

    CUDPdriver* udp = new CUDPdriver();
    udp->listen(8080);

    while(true)
    {
        usleep(1000);
        //receive data
        udp->recv_data(buffer,FRAME_LENGTH);
        //判断数据帧头是否正确
        if((buffer[0] == xd_frame_head_high) && (buffer[1] == xd_frame_head_low)
                && (buffer[2] == xd_frame_head_high) && (buffer[3] == xd_frame_head_low))
        {
            //计算该包数据包数
            xd_packet_number = buffer[10] * BYTE_LENGTH + buffer[11];
            //计算该帧帧头
            xd_frame_number = buffer[8] * BYTE_LENGTH + buffer[9];
            //判断是否为第一包 数据共四包
            if(0 == xd_packet_number)
            {
                /*判断数据类型*/
                //窄带数据分类
                if((buffer[4] == xd_narrow_high) && (buffer[5] == xd_narrow_low))
                {
                    //窄带分类数据
                    xd_sort_result = buffer[23] * BYTE_LENGTH * 3
                           + buffer[22] * BYTE_LENGTH * 2
                           + buffer[21] * BYTE_LENGTH * 1
                           + buffer[20];
                    emit rec_result(xd_sort_result, 'N');
                    #if DEBUG_TEST_VERSION
                        qDebug()<<"SORT NUMBER : " + xd_sort_result;
                    #endif
                    //数据长度 32bit数据单位
                    xd_data_length = buffer[6] * BYTE_LENGTH + buffer[7];
                    //有效数据长度 32bit数据单位
                    xd_valid_data_length = buffer[13] * BYTE_LENGTH + buffer[14];
                    #if DEBUG_TEST_VERSION
                        qDebug()<<"DATA LENGTH : " + xd_data_length;
                        qDebug()<<"VAILD DATA LENGTH : " + xd_valid_data_length;
                    #endif
                    //计算包数
                    int packet_count = 0;
                    if(((xd_data_length + xd_frame_length * 4) % FRAME_LENGTH) == 0)
                    {
                        packet_count = (xd_data_length + xd_frame_length * 4) / FRAME_LENGTH;
                        #if DEBUG_TEST_VERSION
                            qDebug()<<"PACKET COUNT : " + packet_count;
                        #endif
                    }
                    else
                    {
                        packet_count = ((xd_data_length + xd_frame_length * 4) / FRAME_LENGTH) + 1;
                        #if DEBUG_TEST_VERSION
                            qDebug()<<"PACKET COUNT : " + packet_count;
                        #endif
                    }

                    //申请数据空间 数据整包
                    uint8_t data_doppler[xd_data_length];
                    memcpy(data_doppler, &buffer[XD_FRANME_HEAD_LENGTH+XD_RESULT_OFFSET],FRAME_LENGTH-XD_FRANME_HEAD_LENGTH+XD_RESULT_OFFSET);
                    for(int i = 0; i < (packet_count-1); i++)
                    {
                        xd_packet_number++;
                        udp->recv_data(buffer,FRAME_LENGTH);
                        //判断帧头与包数是否匹配
                        if(((buffer[8] * BYTE_LENGTH + buffer[9]) == xd_frame_number)
                          && ((buffer[10] * BYTE_LENGTH + buffer[11]) == xd_packet_number))
                        {
                            memcpy(&data_doppler[(FRAME_LENGTH-XD_FRANME_HEAD_LENGTH) * (i+1) ],
                                    &buffer[XD_FRANME_HEAD_LENGTH],
                                    FRAME_LENGTH - XD_FRANME_HEAD_LENGTH);
                        }
                        //丢数
                        else{
                            qDebug()<<"WARING: DATA ISORDERED";
                            break;
                        }

                    }
                    emit rec_data(data_doppler,(int)xd_valid_data_length,'N');

                }



                //宽带识别数据
                else if((buffer[4] == xd_broad_high) && (buffer[5] == xd_broad_low))
                {
                   //宽带识别结果
                    xd_recognize_result = buffer[23] * BYTE_LENGTH * 3
                           + buffer[22] * BYTE_LENGTH * 2
                           + buffer[21] * BYTE_LENGTH * 1
                           + buffer[20];
                    emit rec_result(xd_recognize_result, 'B');
                    #if DEBUG_TEST_VERSION
    //                    qDebug()<<"RECOGNIZE NUMBER : " + xd_recognize_result;
                    #endif
                    //数据长度 32bit数据单位
                    xd_data_length = buffer[6] * BYTE_LENGTH + buffer[7];
                    //有效数据长度 32bit数据单位
                    xd_valid_data_length = buffer[13] * BYTE_LENGTH + buffer[14];
                    #if DEBUG_TEST_VERSION
                        qDebug()<<"DATA LENGTH : " + xd_data_length;
                        qDebug()<<"VAILD DATA LENGTH : " + xd_valid_data_length;
                    #endif
                    //计算包数
                    uint packet_count = 0;
                    if(((xd_data_length + xd_frame_length * 4) % FRAME_LENGTH) == 0)
                    {
                        packet_count = (xd_data_length + xd_frame_length * 4) / FRAME_LENGTH;
                        #if DEBUG_TEST_VERSION
                            qDebug()<<"PACKET COUNT : " + packet_count;
                        #endif
                    }
                    else
                    {
                        packet_count = ((xd_data_length + xd_frame_length * 4) / FRAME_LENGTH) + 1;
                        #if DEBUG_TEST_VERSION
                            qDebug()<<"PACKET COUNT : " + packet_count;
                        #endif
                    }

                    //申请数据空间 数据整包
                    uint8_t data_harrp[xd_data_length];
                    memcpy(data_harrp, &buffer[XD_FRANME_HEAD_LENGTH+XD_RESULT_OFFSET],FRAME_LENGTH-XD_FRANME_HEAD_LENGTH+XD_RESULT_OFFSET);
                    for(uint32_t i = 0; i < (packet_count-1); i++)
                    {
                        xd_packet_number++;
                        udp->recv_data(buffer,FRAME_LENGTH);
                        //判断帧头与包数是否匹配
                        if(((buffer[8] * BYTE_LENGTH + buffer[9]) == xd_frame_number)
                          && ((buffer[10] * BYTE_LENGTH + buffer[11]) == xd_packet_number))
                        {
                            memcpy(&data_harrp[(FRAME_LENGTH-XD_FRANME_HEAD_LENGTH) * (i+1) ],
                                    &buffer[XD_FRANME_HEAD_LENGTH],
                                    FRAME_LENGTH - XD_FRANME_HEAD_LENGTH);
                        }
                        //丢数
                        else{
                            qDebug()<<"WARING: DATA ISORDERED";
                            break;
                        }
                    }
                    //调用绘制数据绘图
                    emit rec_data(data_harrp,(int)xd_valid_data_length,'B');
                }
                else qDebug()<<"ERROR: DATA TYPE FAULTS";
            }
            else qDebug()<<"WARING: NOT FIRST PACKET ";
        }
        else qDebug()<<"ERROR: FRAME HEAD FAULTS";
    }
}
